package com.iris.jvmtest.gc;
/**
 * @date : 2017年10月11日 下午5:07:49
 * @author : Iris.Xiao
 * @version : 1.0
 * @description : 解释对象置空的好处 -verbose：gc
*/
public class GcTest {
	public static void main(String[] args) {
		//1.并没有回收这64MB的内存,placeholder还处于作用域之内，虚拟机自然不敢回收placeholder的内存
		byte[] placeholder=new byte[64*1024*1024];
		System.gc();
		

		//2.还是没有回收这64MB的内存代码虽然已经离开了
		//placeholder的作用域，但在此之后，没有任何对局部变量表的读写操作，placeholder原本所
		//占用的Slot还没有被其他变量所复用，所以作为GC Roots一部分的局部变量表仍然保持着对
		//它的关联。这手动将其设置为null值（用来代替那句int a=0，把变量对应的局部变量表
		//Slot清空）便不见得是一个绝对无意义的操作
		{
			byte[] placeholder1=new byte[64*1024*1024];
		}
		System.gc();

		//3.回收64MB的内存
		//这种操作可以作为一种在极特殊情形（对象
		//占用内存大、此方法的栈帧长时间不能被回收、方法调用次数达不到JIT的编译条件）下
		//的“奇技”来使用
		{
			byte[] placeholder3=new byte[64*1024*1024];
		}
		int i=9;
		System.gc();
		
		/**
		 * 赋null值的操作在某些情况下确实是有用的，但笔者的观点是不应当对赋null值的操作有过多的依赖，
		 * 原因有两点，
		 * 从编码角度讲，以恰当的变量作用域来控制变量回收时间才是最优雅的解决方法
		 * 赋null值的操作在经过JIT编译优化后就会被消除掉，这时候将变量设置为null就是没有意义的。
		 * 代码清单2在经过JIT编译后，System.gc（）执行时就可以正确地回收掉内存，无须写成代码清单3的样子。
		 */
	}

}
